package com.ocom.company.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.ocom.common.entity.company.EntityFlowApprover;
import com.ocom.common.entity.company.EntityFlowConfig;
import com.ocom.common.entity.company.EntityFlowPushInfo;
import com.ocom.common.enums.DataSourceEnum;
import com.ocom.common.enums.MasterSlaveEnum;
import com.ocom.common.request.company.GetFlowInstanceListRequest;
import com.ocom.common.vo.company.FlowInstanceInfoVo;
import com.ocom.common.vo.company.GetFlowInstanceListVo;
import com.ocom.company.dao.IDaoFlowConfig;
import com.ocom.company.service.FlowApproverService;
import com.ocom.company.service.FlowConfigService;
import com.ocom.company.service.FlowPushInfoService;
import com.ocom.mysql.aspect.DataSourceAspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Service
public class FlowConfigServiceImpl  extends ServiceImpl<IDaoFlowConfig, EntityFlowConfig> implements FlowConfigService {
    @Autowired
    private FlowApproverService flowApproverService;

    @Autowired
    private FlowPushInfoService flowPushInfoService;

    @Override
    @DataSourceAspect(type= DataSourceEnum.PART_DB,isMaster = MasterSlaveEnum.SLAVE)
    public List<EntityFlowConfig> getFlowConfig(Long companyId, String flowCode, Integer deptType) {
        return this.list(Wrappers.lambdaQuery(EntityFlowConfig.class).eq(EntityFlowConfig::getComId,companyId).eq(EntityFlowConfig::getFlowKey,flowCode).gt(EntityFlowConfig::getDeptType,deptType));
    }

    @Override
    @DataSourceAspect(type= DataSourceEnum.PART_DB,isMaster = MasterSlaveEnum.SLAVE)
    public EntityFlowConfig getFlowConfigByKeyword(Long companyId, String flowKeyword, Integer deptType) {
        return this.getOne(Wrappers.lambdaQuery(EntityFlowConfig.class)
                .eq(EntityFlowConfig::getComId,companyId)
                .eq(EntityFlowConfig::getApplyKey,flowKeyword)
                .gt(EntityFlowConfig::getDeptType,deptType)
                .last("limit 1"));
    }

    @Override
    @DataSourceAspect(type= DataSourceEnum.PART_DB,isMaster = MasterSlaveEnum.MASTER)
    public boolean save(Long companyId, EntityFlowConfig entityFlowConfig) {
        return this.save(entityFlowConfig);
    }

    @Override
    @DataSourceAspect(type= DataSourceEnum.PART_DB,isMaster = MasterSlaveEnum.SLAVE)
    public EntityFlowConfig getOne(Long companyId, EntityFlowConfig entityFlowConfig) {
        return this.getOne(Wrappers.lambdaQuery(EntityFlowConfig.class).eq(EntityFlowConfig::getApplyKey,entityFlowConfig.getApplyKey()).eq(EntityFlowConfig::getComId,entityFlowConfig.getComId()).last("limit 1"));
    }

    @Override
    @DataSourceAspect(type= DataSourceEnum.PART_DB,isMaster = MasterSlaveEnum.MASTER)
    public boolean update(Long companyId, EntityFlowConfig entityFlowConfig) {
        return this.update(entityFlowConfig,Wrappers.lambdaQuery(EntityFlowConfig.class).eq(EntityFlowConfig::getApplyKey,entityFlowConfig.getApplyKey()).eq(EntityFlowConfig::getComId,entityFlowConfig.getComId()));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @DataSourceAspect(type= DataSourceEnum.PART_DB,isMaster = MasterSlaveEnum.MASTER)
    public boolean remove(Long companyId, EntityFlowConfig entityFlowConfig) {
        this.remove(Wrappers.lambdaQuery(EntityFlowConfig.class).eq(EntityFlowConfig::getComId,entityFlowConfig.getComId()).eq(EntityFlowConfig::getFlowId,entityFlowConfig.getFlowId()));

        EntityFlowApprover entityFlowApprover = new EntityFlowApprover();
        entityFlowApprover.setComId(companyId);
        entityFlowApprover.setFId(entityFlowConfig.getFlowId());
        this.flowApproverService.remove(companyId,entityFlowApprover);

        EntityFlowPushInfo entityFlowPushInfo = new EntityFlowPushInfo();
        entityFlowPushInfo.setComId(companyId);
        entityFlowPushInfo.setFId(entityFlowConfig.getFlowId());
        this.flowPushInfoService.remove(companyId,entityFlowPushInfo);
        return true;
    }

    @Override
    @DataSourceAspect(type= DataSourceEnum.PART_DB,isMaster = MasterSlaveEnum.SLAVE)
    public EntityFlowConfig getInfoDefKey(Long companyId,String defKey) {
        QueryWrapper<EntityFlowConfig>  queryWrapper =new QueryWrapper<>();
        queryWrapper.eq("com_id",companyId);
        queryWrapper.eq("flow_keyword",defKey);
        queryWrapper.last("limit 1");
        return this.getOne(queryWrapper);
    }

    @Override
    @DataSourceAspect(type= DataSourceEnum.PART_DB,isMaster = MasterSlaveEnum.SLAVE)
    public Page<GetFlowInstanceListVo> getFlowInstanceList(Long companyId, GetFlowInstanceListRequest getFlowInstanceListRequest) {
        if(getFlowInstanceListRequest.getPage()==null){
            getFlowInstanceListRequest.setPage(1);
        }
        if(getFlowInstanceListRequest.getSize()==null){
            getFlowInstanceListRequest.setSize(50);
        }
        if(ObjectUtil.isEmpty(getFlowInstanceListRequest.getStatus())){
            getFlowInstanceListRequest.setStatus(-1);
        }
        List<String> deptIds = new ArrayList<>();
        List<String>  applyKeys = new ArrayList<>();
        if(ObjectUtil.isNotEmpty(getFlowInstanceListRequest.getDeptIds())){
            deptIds = Lists.newArrayList(getFlowInstanceListRequest.getDeptIds().split(","));
        }
        if(ObjectUtil.isNotEmpty(getFlowInstanceListRequest.getApplyKeys())){
            applyKeys = Lists.newArrayList(getFlowInstanceListRequest.getApplyKeys().split(","));
        }
        IPage<GetFlowInstanceListVo> page = new Page<>();
        page.setCurrent(getFlowInstanceListRequest.getPage());
        page.setSize(getFlowInstanceListRequest.getSize());
        QueryWrapper<GetFlowInstanceListRequest> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .eq("D.com_id",getFlowInstanceListRequest.getComId())
                .eq("P.com_id",getFlowInstanceListRequest.getComId())
                .eq("F.com_id",getFlowInstanceListRequest.getComId())
                .eq("B.com_id",getFlowInstanceListRequest.getComId())
                .between("apply_time",getFlowInstanceListRequest.getStartTime(),getFlowInstanceListRequest.getEndTime())
                .in(ObjectUtil.isNotEmpty(getFlowInstanceListRequest.getDeptIds()),"D.dept_id",deptIds)
                .like(ObjectUtil.isNotEmpty(getFlowInstanceListRequest.getPName()),"P.p_name",getFlowInstanceListRequest.getPName())
                .like(ObjectUtil.isNotEmpty(getFlowInstanceListRequest.getPCode()),"P.p_code",getFlowInstanceListRequest.getPCode())
                .in(ObjectUtil.isNotEmpty(getFlowInstanceListRequest.getApplyKeys()),"F.flow_keyword",applyKeys)
                .eq(getFlowInstanceListRequest.getStatus() > -1,"B.status",getFlowInstanceListRequest.getStatus())
        ;
        queryWrapper.orderByDesc("B.create_time");

        List<GetFlowInstanceListVo>  page1 = this.baseMapper.getFlowInstanceListVo((getFlowInstanceListRequest.getPage()-1)*getFlowInstanceListRequest.getSize(),getFlowInstanceListRequest.getSize(),queryWrapper);
        Long coo = this.baseMapper.getFlowInstanceCount(page,queryWrapper);
        Page<GetFlowInstanceListVo> getFlowInstanceListVoPage =new Page<>(getFlowInstanceListRequest.getPage(),getFlowInstanceListRequest.getSize());
        getFlowInstanceListVoPage.setRecords(page1);
        getFlowInstanceListVoPage.setTotal(coo);
        return getFlowInstanceListVoPage;
    }

    @Override
    @DataSourceAspect(type= DataSourceEnum.PART_DB,isMaster = MasterSlaveEnum.SLAVE)
    public List<FlowInstanceInfoVo> flowInstanceInfoList(Long companyId, List<Integer> businessKeyList) {
        QueryWrapper<FlowInstanceInfoVo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("B.com_id",companyId)
                .in("B.business_id",businessKeyList)
                .orderByDesc("applyTime");
        return this.baseMapper.flowInstanceList(queryWrapper);
    }
}
